package com.springcloud.hystrixdemo

import com.netflix.hystrix.HystrixThreadPoolKey
import com.netflix.hystrix.strategy.HystrixPlugins
import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy
import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategyDefault
import com.netflix.hystrix.strategy.concurrency.HystrixContextCallable
import com.netflix.hystrix.strategy.properties.HystrixProperty
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.cloud.netflix.hystrix.EnableHystrix
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard
import org.springframework.cloud.netflix.turbine.EnableTurbine
import org.springframework.cloud.openfeign.EnableFeignClients
import org.springframework.web.context.request.RequestContextHolder
import springfox.documentation.swagger2.annotations.EnableSwagger2

import java.util.concurrent.BlockingQueue
import java.util.concurrent.Callable
import java.util.concurrent.ThreadPoolExecutor
import java.util.concurrent.TimeUnit

@SpringBootApplication
@EnableSwagger2
@EnableFeignClients

@EnableHystrix//启用短路保护

/*
    HystrixDashBoard应该独立于被监控的服务单独存在,但这里为了阐述将他们放在同一个项目中
 */
@EnableHystrixDashboard//启用Hystrix仪表盘功能
@EnableTurbine//开启turbine
class HystrixDemoApplication {

    static void main(String[] args) {

        registerConcurrencyStrategy()

         SpringApplication.run HystrixDemoApplication, args
    }


    static registerConcurrencyStrategy(){
        //添加Hystrix插件:注册一个自定义的并发策略,用于ThreadLocal数据的转移

        HystrixPlugins.instance.registerConcurrencyStrategy(//该方法只能调用一次
                new HystrixConcurrencyStrategy() {
            //该方法执行于原线程
            @Override
            def <T> Callable<T> wrapCallable(Callable<T> callable) {//这里的callable就是被Hystrix包装的函数体(命令)
                //println("wrapCallable方法执行线程:${Thread.currentThread().name}")
                new ThreadLocalCallable<T>(callable: callable)
            }
            static class ThreadLocalCallable<T> implements Callable<T>{

                Callable<T> callable

                //该方法执行于Hystrix线程
                @Override
                T call() throws Exception {
               // println("callable.call执行线程:${Thread.currentThread().name}")
                    return callable.call()
                }
            }

        })

    }



}
